home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / comm2 / parnet.lha / parnet / sources / unit_dgr.c < prev    next >
C/C++ Source or Header  |  1993-11-09  |  4KB  |  198 lines

  1.  
  2. /*
  3.  *  UNIT_DGR.C            DATAGRAM PROTOCOL
  4.  */
  5.  
  6. #include "defs.h"
  7.  
  8. void DGramBeginIO(Iob *);
  9. void DGramAbortIO(Iob *);
  10. void DGramClose(Iob *);
  11. void DGramData(int, Packet *, long);
  12.  
  13. void UnitDGramOpen(Iob *, long, long);
  14.  
  15. /*
  16.  *  Called under Forbid
  17.  */
  18.  
  19. void
  20. UnitDGramOpen(iob, unitnum, flags)
  21. Iob *iob;
  22. long unitnum;
  23. long flags;
  24. {
  25.     Unit *unit;
  26.  
  27.     if (unit = FindUnitForPort(iob->io_Port)) {
  28.     if (unit->BeginIO != DGramBeginIO) {
  29.         iob->io_Error = PPERR_PORT_IN_USE;
  30.         return;
  31.     }
  32.     } else {
  33.     unit = AllocUnit(iob, DGramBeginIO, DGramAbortIO, DGramData, DGramClose);
  34.     }
  35.     iob->io_Unit = unit;
  36.     ++unit->RefCnt;
  37. }
  38.  
  39.  
  40. void
  41. DGramClose(iob)
  42. Iob *iob;
  43. {
  44.     Unit *unit = iob->io_Unit;
  45.  
  46.     if (--unit->RefCnt == 0) {
  47.     FreeUnit(unit);
  48.     }
  49.     iob->io_Unit = NULL;
  50. }
  51.  
  52. /*
  53.  *  UnitDGramData() is called whenever a low level network operation
  54.  *            completes for the given unit.  cmd is:
  55.  *
  56.  *            'r'     received data packet
  57.  *            'w'     wrote data packet
  58.  *            'W'     timeout writing data packet
  59.  *
  60.  *            The routine is called with the unix locked.
  61.  *
  62.  *  WARNING:    This call may not requeue synchronous packets, a lockout
  63.  *        will result.
  64.  */
  65.  
  66. void
  67. DGramData(cmd, packet, actual)
  68. int cmd;
  69. Packet *packet;
  70. long actual;    /*  'w', 'W'    */
  71. {
  72.     Unit *unit = packet->io_Unit;
  73.     Iob *iob = packet->iob;        /*    NULL for 'r'    */
  74.     long n;
  75.  
  76.     switch(cmd) {
  77.     case 'r':
  78. #ifdef DEBUG
  79.     sprintf(StickyPort->DebugBuf, " RDDRG %d",actual);
  80. #endif
  81.  
  82.     if (iob = (Iob *)RemHead(&unit->PendIOR)) {
  83.         iob->io_Flags &= ~IOF_QUEUED;
  84.  
  85.         n = actual;
  86.         if (n < 0)
  87.         n = 0;
  88.         if (n > iob->io_Length) {
  89.         n = iob->io_Length;
  90.         iob->io_Error = PPERR_WARN_OVFLOW;
  91.         }
  92.         actual -= n;
  93.         movmem((char *)packet->Data1, (char *)iob->io_Data, n);
  94.  
  95.         if (iob->io_Length2 && actual > 0) {    /*  a second data buffer    */
  96.         if (actual > iob->io_Length2)
  97.             actual = iob->io_Length2;
  98.         movmem((char *)packet->Data1 + n, (char *)iob->io_Data2, actual);
  99.         n += actual;
  100.         }
  101.         iob->io_Actual = n;
  102.  
  103.         if ((iob->io_Flags & IOF_QUICK) == 0)
  104.         ReplyMsg(&iob->io_Message);
  105.     }
  106.  
  107.     /*
  108.      *  Note that if no read requests are pending the datagram is
  109.      *  thrown away.
  110.      */
  111.  
  112.     FreeParPacket(packet);
  113.     break;
  114.     case 'W':
  115. #ifdef DEBUG
  116.     sprintf(StickyPort->DebugBuf, " TMDRG %d",actual);
  117. #endif
  118.  
  119.     Remove(iob);
  120.     iob->io_Flags &= ~IOF_QUEUED;
  121.     iob->io_Error = 1;
  122.     iob->io_Actual = actual;
  123.     if ((iob->io_Flags & IOF_QUICK) == 0)
  124.         ReplyMsg(&iob->io_Message);
  125.     FreeParPacket(packet);
  126.     break;
  127.     case 'w':
  128. #ifdef DEBUG
  129.     sprintf(StickyPort->DebugBuf, " WRDRG %d",actual);
  130. #endif
  131.  
  132.     Remove(iob);
  133.     iob->io_Flags &= ~IOF_QUEUED;
  134.     iob->io_Actual = actual;
  135.     if ((iob->io_Flags & IOF_QUICK) == 0)
  136.         ReplyMsg(&iob->io_Message);
  137.     FreeParPacket(packet);
  138.     break;
  139.     }
  140. }
  141.  
  142. void
  143. DGramBeginIO(iob)
  144. Iob *iob;
  145. {
  146.     Unit *unit = iob->io_Unit;
  147.     Packet *packet;
  148.  
  149.     iob->io_Error = 0;
  150.     iob->io_Actual = 0;
  151.     iob->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  152.  
  153.     switch(iob->io_Command) {
  154.     case CMD_READ:
  155.     LockAddr(unit->UnitLock);
  156.     iob->io_Flags &= ~IOF_QUICK;
  157.     iob->io_Flags |= IOF_QUEUED;
  158.     AddTail(&unit->PendIOR, iob);
  159.     UnlockAddr(unit->UnitLock);
  160.     return;
  161.     case CMD_WRITE:
  162.     packet = AllocParPacket(iob, unit, iob->io_Data, iob->io_Length, iob->io_Data2, iob->io_Length2);
  163.     LockAddr(unit->UnitLock);
  164.     AddTail(&unit->PendIOW, iob);
  165.     UnlockAddr(unit->UnitLock);
  166.  
  167.     QueuePacketForWrite(packet);
  168.     return;
  169.     default:
  170.     CtlBeginIO(iob);
  171.     return;
  172.     }
  173. }
  174.  
  175. /*
  176.  *  Abort a read or write request.  Currently only read requests may be
  177.  *  aborted.
  178.  */
  179.  
  180. void
  181. DGramAbortIO(iob)
  182. Iob *iob;
  183. {
  184.     if (iob->io_Command == CMD_READ) {
  185.     LockAddr(iob->io_Unit->UnitLock);
  186.     if ((iob->io_Flags & (IOF_QUEUED|IOF_RUN)) == IOF_QUEUED) {
  187.         Remove(iob);
  188.         UnlockAddr(iob->io_Unit->UnitLock);
  189.         iob->io_Flags &= ~IOF_QUEUED;
  190.         iob->io_Error = -1;     /*    ??? */
  191.         ReplyMsg(&iob->io_Message);
  192.     } else {
  193.         UnlockAddr(iob->io_Unit->UnitLock);
  194.     }
  195.     }
  196. }
  197.  
  198.